﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//using System.Text.Json;
using Newtonsoft.Json;

namespace Infrastructure
{
    public class RedisHelper
    {
        private readonly string _connectionString;
        private readonly string _instanceName;
        private readonly int _defaultDB;
        private StackExchange.Redis.IDatabase _cache;
        private readonly ConnectionMultiplexer _connection;

        public RedisHelper(string connectionString, string instanceName, int defaultDB = 0)
        {
            _connectionString = connectionString;
            _instanceName = instanceName;
            _defaultDB = defaultDB;
            _connection = ConnectionMultiplexer.Connect(_connectionString);
            _cache = _connection.GetDatabase(_defaultDB);
        }

        //public IDatabase GetDatabase()
        //{
        //    return _cache;
        //}

        public IServer GetServer(int endPointsIndex = 0)
        {
            var confOption = ConfigurationOptions.Parse(_connectionString);
            return _connection.GetServer(confOption.EndPoints[endPointsIndex]);
        }

        public ISubscriber GetSubscriber()
        {
            return _connection.GetSubscriber();
        }
        #region 增
        public bool SetCache<T>(string key, T value, TimeSpan? expireTime = null)
        {
            try
            {
                var jsonOption = new JsonSerializerSettings
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                };
                string strValue = JsonConvert.SerializeObject(value, jsonOption);

                if (string.IsNullOrEmpty(strValue)) return false;

                return _cache.StringSet(key, strValue, expireTime);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error setting cache for key {key}: {ex.Message}");
                return false;
            }
        }

        #endregion


        #region delete
        // 获取匹配特定模式的所有键（请谨慎使用，尤其是在包含大量键的生产环境中）
        public IEnumerable<RedisKey> GetAllKeys(string pattern)
        {
            var endPoint = _connection.GetEndPoints().First();
            var server = _connection.GetServer(endPoint);
            return server.Keys(pattern: $"{_instanceName}:{pattern}*");
        }

        // 删除匹配特定前缀的所有缓存键
        public void DeleteKeysByPrefix(string prefix)
        {
            var keysToDelete = GetAllKeys(prefix).ToArray();
            if (keysToDelete.Any())
            {
                _cache.KeyDelete(keysToDelete);
            }
        }

        public bool RemoveCache(string key)
        {
            try
            {
                return _cache.KeyDelete(key);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error removing cache for key {key}: {ex.Message}");
                return false;
            }
        }
        #endregion



        public bool Exists(string key)
        {
            try
            {
                return _cache.KeyExists(key);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error checking existence for key {key}: {ex.Message}");
                return false;
            }
        }

        public T GetCache<T>(string key)
        {
            if (!Exists(key)) return default;

            try
            {
                var value = _cache.StringGet(key);
                if (string.IsNullOrEmpty(value)) return default;
                return JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error getting cache for key {key}: {ex.Message}");
                return default;
            }
        }








        // 释放ConnectionMultiplexer资源
        public void Dispose()
        {
            _connection?.Dispose();
        }
    }
}
